/*
 * Pos.cpp
 *
 *  Created on: 2012-9-8
 *      Author: yangentao@gmail.com
 */

#include "Pos.h"

Pos::Pos() :
		mgr(0) {
}
Pos::Pos(PosManager* mgr_, boost::shared_ptr<int> value_) {
	mgr = mgr_;
	value = value_;
}

Pos::~Pos() {
	release();
}
void Pos::release() {
	if (mgr && value.get()) {
		if (value.use_count() == 2) {
			int n = index();
			value.reset();
			mgr->releasePos(n);
		}
	}
	mgr = 0;
	value.reset();
}

Pos PosManager::createPos(int index) {
	assert(index >=0);
	PosMap::const_iterator it = posMap.find(index);
	if (it != posMap.end()) {
		return Pos(this, it->second);
	} else {
		boost::shared_ptr<int> shareIndex(new int(index));
		posMap[index] = shareIndex;
		return Pos(this, shareIndex);
	}
}
void PosManager::releasePos(int index) {
	PosMap::const_iterator it = posMap.find(index);
	if (it != posMap.end()) {
		if (it->second.use_count() == 1) {
			posMap.erase(it);
		}
	}
}

void PosManager::onTextReplaced(int from, const String& removeText, const String& insertText){
	int removLength = removeText.length();
	int insertLength = insertText.length();

	int delTo = from + removLength;
	int delta = insertLength - removLength;
	PosMap::iterator it = posMap.lower_bound(from);
	if (it == posMap.end()) {
		return;
	}
	Vector<boost::shared_ptr<int> > updateValues(posMap.size());
	while (it != posMap.end()) {
		int& val = *(it->second.get());
		if (val < delTo) { //delete
			val = -1;
		} else { //update;
			updateValues.append(it->second);
		}
		it = posMap.erase(it);
	}
	for (int i = 0; i < updateValues.size(); ++i) {
		boost::shared_ptr<int>& sn = updateValues[i];
		int& v = (*sn.get());
		v += delta;
		posMap[v] = sn;
	}
}

